from models.dao import user_dao, user_role_dao, role_permission_dao
from models.database import SessionLocal
from utils.password_util import hash_or_store_password

def getUsers(skip: int = 0, limit: int = 100):
    with SessionLocal() as db:
        users = user_dao.getUsers(db, skip=skip, limit=limit)
        return [u.to_dict() for u in users]

def getUser(user_id: str):
    with SessionLocal() as db:
        userModel = user_dao.getUser(db, user_id=user_id)
        if userModel is None:
            return None
        return userModel.to_dict()

def getUserByUsername(username: str):
    with SessionLocal() as db:
        userModel = user_dao.getUserByUsername(db, username=username)
        if userModel is None:
            return None
        return userModel.to_dict()

def createUser(user_data: dict):
    with SessionLocal() as db:
        user_data['hashed_password'] = hash_or_store_password(user_data['password'])
        del user_data['password']
        newUserModel = user_dao.createUser(db, user_data)
        if newUserModel is None:
            return None
        return newUserModel.to_dict()

def updateUser(user_id: str, user_data: dict):
    with SessionLocal() as db:
        if 'password' in user_data:
            user_data['hashed_password'] = hash_or_store_password(user_data['password'])
            del user_data['password']
        updatedUserModel = user_dao.updateUser(db, user_id=user_id, user=user_data)
        if updatedUserModel is None:
            return None
        return updatedUserModel.to_dict()

def deleteUser(user_id: str):
    with SessionLocal() as db:
        # Check if user exists
        user_to_delete = user_dao.getUser(db, user_id)
        if user_to_delete is None:
            return False

        # Delete associated user roles
        user_role_dao.delete_user_roles_by_user_id(db, user_id)

        # Delete the user itself
        return user_dao.deleteUser(db, user_id=user_id)

def searchUsers(keyword: str = None, skip: int = 0, limit: int = 100, sort_by: str = "username", sort_order: str = "asc", status: str = None):
    with SessionLocal() as db:
        users = user_dao.searchUsers(db, keyword=keyword, skip=skip, limit=limit, sort_by=sort_by, sort_order=sort_order, status=status)
        return [u.to_dict() for u in users]


def get_user_permissions(user_id: str):
    with SessionLocal() as db:
        # Get all roles for the user
        user_roles = user_role_dao.get_roles_by_user_id(db, user_id)
        if not user_roles:
            return []

        # Use a set to store unique permissions
        permissions = set()

        # Iterate through each role and get its permissions
        for user_role in user_roles:
            role_permissions = role_permission_dao.get_permissions_by_role_id(db, user_role.role_id)
            for rp in role_permissions:
                # Add the (endpoint, method) tuple to the set
                if rp.permission:
                    permissions.add((rp.permission.endpoint, rp.permission.method))

        return list(permissions)


